package com.example.logistics_manage.service.serviceImpl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.logistics_manage.config.OssConfig;
import com.example.logistics_manage.config.SmsConfig;
import com.example.logistics_manage.mapper.RoleMapper;
import com.example.logistics_manage.mapper.UserMapper;
import com.example.logistics_manage.pojo.User;
import com.example.logistics_manage.pojo.dto.UserDto;
import com.example.logistics_manage.pojo.dto.UserRoleDto;
import com.example.logistics_manage.result.appexception.AppException;
import com.example.logistics_manage.result.restful.R;
import com.example.logistics_manage.result.restful.ResponseEunm;
import com.example.logistics_manage.service.IUserService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.util.*;

@Service
public class UserService extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    OssConfig ossConfig;
//    @Autowired
//    OSS ossClient;
    @Autowired
    IAcsClient client;
    @Autowired
    SmsConfig smsConfig;
    @Override
    public R<UserDto> login(User user) {

        User login = userMapper.login(user);
        System.out.println(login);
        if (login == null){
            return new R<>(ResponseEunm.USERNAME_OR_PASSWORD_INVALIDATE,null);
        }else {
            UserDto userDto = new UserDto(login);
            userDto.setRoleName(roleMapper.findRoleNameById(login.getUserRole()));
            try {
                Algorithm algorithm = Algorithm.HMAC256("logistics");
                String token = JWT.create()
                        .withIssuer("quhao")
                        .withIssuedAt(new Date())
                        .withClaim(login.getUserName(),login.getUserRole())
                        .sign(algorithm);
                userDto.setToken(token);
            } catch (JWTCreationException e){
                throw e;
            }
            return new R<>(ResponseEunm.SUCCESS,userDto);
        }
    }

    @Override
    public R<User> register(User user) {
        if(userMapper.registerCheck(user.getUserName()) == null && userMapper.findByPhone(user.getPhone()) == null) {
            if (user.getUserRole() < 6){
                user.setJobId((int) (100000+count()));
                System.out.println(user.getJobId());
            }else {
                user.setJobId(0);
            }
            if(save(user)){
                return new R<>(ResponseEunm.SUCCESS,null);
            }
            return new R<>(ResponseEunm.ADD_FAIL,null);
        }
        return new R<>(ResponseEunm.USER_ALREADY_EXISTS,null);
    }

    @Override
    public void sendCheckCode(String phone, String checkCode) {

// 请求对象
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", smsConfig.getRegionId());
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", smsConfig.getSignName());
        request.putQueryParameter("TemplateCode", "SMS_150181589");
        Map<String,String> map = new HashMap<>();
        map.put("code",checkCode);
//把对象转换成json
        Gson gson = new Gson();
        request.putQueryParameter("TemplateParam",gson.toJson(map));

//用客户端发送给阿里云客户端，，发送短信
        try {
            CommonResponse response = client.getCommonResponse(request);
            //得到json字符串格式的响应结果
            String data = response.getData();
            //解析json字符串格式的响应结果
            // 吧阿里云响应给我们的json 字符串 转成map
            Map<String, String> map1 = gson.fromJson(data,Map.class);
            String retrueCode = map1.get("Code");
            String message = map1.get("Message");
            if ("isv.BUSINESS_LIMIT_CONTROL".equals(retrueCode)) {
                log.error("短信发送过于频繁 " + "【code】" + retrueCode + ", 【message】" + message);
                throw new AppException(ResponseEunm.SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL);
            }
            if (!"OK".equals(retrueCode)) {
                log.error("短信发送失败 " + " - code: " + retrueCode + ", message: " + message);
                throw new AppException(ResponseEunm.SMS_SEND_ERROR);
            }
        }catch (ClientException e){
            throw  new AppException(ResponseEunm.SUCCESS);
        }
    }

    @Override
    public User findByPhone(Long phone) {
        return userMapper.findByPhone(phone);
    }

    @Override
    public void updateCodeByPhone(Integer code,Long phone) {
        userMapper.updateCodeByPhone(code,phone);
    }

    @Override
    public R<UserDto> loginByCode(Integer code,Long phone) {
        User user = userMapper.findByPhone(phone);
        if (!user.getCode().equals(code)){
            return new R<>(ResponseEunm.CODE_SMS_ERROR,null);
        }
        UserDto userDto = new UserDto(user);
        userDto.setRoleName(roleMapper.findRoleNameById(user.getUserRole()));
        System.out.println(userDto);
        return new R<>(ResponseEunm.SUCCESS,userDto);

    }

    @Override
    public String upload(InputStream inputStream, String yunFileName, String originalFileName) {

            OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(),ossConfig.getAccessKeyId(),ossConfig.getAccessKeySecret());
        if (!ossClient.doesBucketExist(ossConfig.getBucketName())) {
            //创建bucket
            ossClient.createBucket(ossConfig.getBucketName());
            //设置oss实例的访问权限：公共读
            ossClient.setBucketAcl(ossConfig.getBucketName(), CannedAccessControlList.PublicRead);
        }

        //文件名：uuid.扩展名
        String fileName = UUID.randomUUID().toString();
        //文件上传至阿里云
        String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
        String key = yunFileName  + "/" + fileName + fileExtension;

        ossClient.putObject(ossConfig.getBucketName(), key, inputStream);

        // 关闭OSSClient。
        ossClient.shutdown();

        //返回url地址
        return "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/" + key;
    }

    @Override
    public R<User> updateImageByPhone(Long phone, String image) {
        if (userMapper.updateImageByPhone(phone, image) != 1){
            return new R<>(ResponseEunm.UPDATE_FAIL,null);
        }
        return new R<>(ResponseEunm.SUCCESS,null);
    }

    @Override
    public int updateUser(User user) {
        return userMapper.updateUser(user);
    }

    @Override
    public List<User> selectByJobId() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUserRole,5);
        return userMapper.selectList(wrapper);
    }

    @Override
    public List<UserRoleDto> selectAllEmp() {
        return userMapper.selectAllEmp();
    }

    @Override
    public int updateRole(User user) {
        return userMapper.updateById(user);
    }

    @Override
    public List<User> selectEmp(User user) {
        return userMapper.selectEmp(user);
    }

    @Override
    public List<User> selectAdmin() {
        Wrapper<User> wrapper = new LambdaQueryWrapper<User>().eq(User::getUserRole,7);
        List<User> users = userMapper.selectList(wrapper);
        return users;
    }

    @Override
    public void deleteAdmin(Integer id) {
        int i = userMapper.deleteById(id);
    }

    @Override
    public List<User> selectAdminBy(User user) {
        return userMapper.selectAdminBy(user);
    }

    @Override
    public List<User> selectDriver() {
        Wrapper<User> wrapper = new LambdaQueryWrapper<User>().eq(User::getUserRole,5);
        return userMapper.selectList(wrapper);
    }

    @Override
    public List<User> selectDriverBy(User user) {
        return userMapper.selectDriverBy(user);
    }

    @Override
    public List<User> selectCustomer() {
        Wrapper<User> wrapper = new LambdaQueryWrapper<User>().eq(User::getUserRole,6);
        return userMapper.selectList(wrapper);
    }

    @Override
    public List<User> selectCustomerBy(User user) {
        return userMapper.selectCustomerBy(user);
    }

}
